package util.logging

//import org.slf4j.{LoggerFactory, Logger}

import LogLevel._
import java.util.logging.{Level, Logger}

/**
 * <p>
 * Created by IntelliJ IDEA.
 * User: zslajchrt
 * Date: Oct 19, 2010
 * Time: 11:31:05 AM
 */
@serializable @SerialVersionUID(1L)
trait Logged {
  @transient
  var l: Logger = null

  protected val thisClass: Class[_] = getClass

  protected def getLoggerName: String = {
    thisClass.getName
  }

  private def logger = if (l != null) l
  else {
    l = Logger.getLogger(getLoggerName)
    l
  }

  protected def getClassAndMethodName(stackOffset: Int): (String, String) = {
    val stack = (new Throwable()).getStackTrace()
    val frame = stack(stackOffset)
    val loggerName: String = getLoggerName
    val className = if (loggerName != frame.getClassName)
      frame.getClassName + "[logger: " + loggerName + "]"
    else
      frame.getClassName
    (className, frame.getMethodName)
  }

  private def logWithThrowable(level: Level, msg: => AnyRef, t: => Throwable) {
    if (logger.isLoggable(level)) {
      val (className, methodName) = getClassAndMethodName(5)
      logger.logp(level, className, methodName, String.valueOf(msg), t)
    }
  }

  private def logWithoutThrowable(level: Level, msg: => AnyRef) {
    if (logger.isLoggable(level)) {
      val (className, methodName) = getClassAndMethodName(5)
      logger.logp(level, className, methodName, String.valueOf(msg))
    }
  }

  def severe(msg: => AnyRef) = {
    logWithoutThrowable(Level.SEVERE, msg)
  }

  def severe(msg: => AnyRef, t: => Throwable) = {
    logWithThrowable(Level.SEVERE, msg, t)
  }

  def warn(msg: => AnyRef) = {
    logWithoutThrowable(Level.WARNING, msg)
  }

  def warn(msg: => AnyRef, t: => Throwable) = {
    logWithThrowable(Level.WARNING, msg, t)
  }

  def info(msg: => AnyRef) = {
    logWithoutThrowable(Level.INFO, msg)
  }

  def info(msg: => AnyRef, t: => Throwable) = {
    logWithThrowable(Level.INFO, msg, t)
  }

  def debug(msg: => AnyRef) = {
    logWithoutThrowable(Level.FINE, msg)
  }

  def debug(msg: => AnyRef, t: => Throwable) = {
    logWithThrowable(Level.FINE, msg, t)
  }

  //private def logger = LoggerFactory.getLogger(thisClass)

  //  private[this] val thisClass: Class[_] = getClass
  //
  //  def isTraceEnabled = logger.isTraceEnabled
  //
  //  def trace(msg: => AnyRef) = if (isTraceEnabled) logger.trace(String.valueOf(msg))
  //
  //  def trace(msg: => AnyRef, t: => Throwable) = if (isTraceEnabled) logger.trace(String.valueOf(msg), t)
  //
  //  def assertLog(assertion: Boolean, msg: => String) = if (assertion) info(msg)
  //
  //  def isDebugEnabled = logger.isDebugEnabled
  //
  //  def debug(msg: => AnyRef) = if (isDebugEnabled) logger.debug(String.valueOf(msg))
  //
  //  def debug(msg: => AnyRef, t: => Throwable) = if (isDebugEnabled) logger.debug(String.valueOf(msg), t)
  //
  //  def isErrorEnabled = logger.isErrorEnabled
  //
  //  def severe(msg: => AnyRef) = if (isErrorEnabled) logger.error(String.valueOf(msg))
  //
  //  def severe(msg: => AnyRef, t: => Throwable) = if (isErrorEnabled) logger.error(String.valueOf(msg), t)
  //
  //  def fatal(msg: AnyRef) = severe(msg)
  //
  //  def fatal(msg: AnyRef, t: Throwable) = severe(msg, t)
  //
  //  def isInfoEnabled = logger.isInfoEnabled
  //
  //  def info(msg: => AnyRef) = if (isInfoEnabled) logger.info(String.valueOf(msg))
  //
  //  def info(msg: => AnyRef, t: => Throwable) = if (isInfoEnabled) logger.info(String.valueOf(msg), t)
  //
  //  def isWarnEnabled = logger.isWarnEnabled
  //
  //  def warn(msg: => AnyRef) = if (isWarnEnabled) logger.warn(String.valueOf(msg))
  //
  //  def warn(msg: => AnyRef, t: => Throwable) = if (isWarnEnabled) logger.warn(String.valueOf(msg), t)
  //
  //  def isEnabledFor(level: LogLevel): Boolean = level match {
  //    case All => isTraceEnabled
  //    case Debug => isDebugEnabled
  //    case Error => isErrorEnabled
  //    case Warn => isWarnEnabled
  //    case Fatal => isErrorEnabled
  //    case Info => isInfoEnabled
  //    case Trace => isTraceEnabled
  //    case Off => !isErrorEnabled
  //  }
  //
  //  def name = logger.getName

}
